# -*- coding:utf-8 -*-
import json
from django.db.models import Q
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from django.db.transaction import atomic

from Apps.user.models import User
from Apps.System.filters.menuFilter import MenuFilter
from Apps.System.filters.permissionsFilter import getMenuByRoleFilter, RoleFilter
from Apps.System.models.role_menu import Role, Menu
from Apps.System.ser.menu_ser import MenuSer, getMenuTreeSer, ParentMenuSer, getMenuSidebarSer
from Apps.System.ser.role_ser import RoleSer, PostRoleSer
from Apps.common.response import SuccessResponse

from Apps.util.request_util import setCreateUser, setModifyUser

import logging

logger = logging.getLogger('django')


class RoleView(ModelViewSet):
    """
    角色新增，角色查询
    """
    queryset = Role.objects.all()
    serializer_class = RoleSer
    filter_class = RoleFilter
    authentication_classes = []


class DelRole(APIView):
    @atomic()
    def post(self, request, *args, **kwargs):
        Role.objects.filter(id__in=request.data).delete()
        return SuccessResponse("12345")


class MenuView(ModelViewSet):
    queryset = Menu.objects.all()
    serializer_class = MenuSer
    filter_class = MenuFilter

    # 创建菜单
    def create(self, request, *args, **kwargs):
        request = setCreateUser(request)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return SuccessResponse(serializer.data)

    # 更新菜单
    def update(self, request, *args, **kwargs):
        request = setModifyUser(request)
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}

        return SuccessResponse(serializer.data)

    # 删除菜单
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return SuccessResponse(121)

    # 列表展示菜单数据
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        # logger.info(queryset)

        #  获取需要查询的所有ID
        allQuerysetId = []
        for item in queryset:
            if item.menuType == '2' and item.parentId != '':
                # 按钮
                allQuerysetId.append(item.id)
                # 二级菜单
                allQuerysetId.append(item.parentId)
                # 一级菜单
                allQuerysetId.append(Menu.objects.filter(id=item.parentId).first().id)
            if item.menuType == '1' and item.parentId != '':
                #  二级菜单
                if item.id not in allQuerysetId:
                    allQuerysetId.append(item.id)
                # 一级菜单
                if item.parentId not in allQuerysetId:
                    allQuerysetId.append(item.parentId)
            if item.menuType == '0':
                # 一级菜单
                if item.id not in allQuerysetId:
                    allQuerysetId.append(item.id)
        # logger.info(allQuerysetId)
        allQueryset = Menu.objects.filter(id__in=allQuerysetId).all()
        # logger.info(allQuerysetId)
        serializer = self.get_serializer(allQueryset, many=True)

        # 构造前端可展示的结构化数据
        # 结构化数据(分三次添加，先添加一级，再二级，再按钮，不然出现-添加按钮是判断不到父级）
        ResponseData = []
        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                # item["menuType"] = "一级菜单"
                ResponseData.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in ResponseData:
                    if firstMenu['id'] == item["parentId"]:
                        item["children"] = []
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

        for item in serializer.data:
            if item["menuType"] == '2':
                for firstMenu in ResponseData:
                    for secondMenu in firstMenu["children"]:
                        if secondMenu["id"] == item["parentId"]:
                            # item["menuType"] = "按钮"
                            secondMenu["children"].append(item)

        return SuccessResponse(ResponseData)


class getMenuTree(APIView):

    def get(self, request, *args, **kwargs):
        queryset = Menu.objects.all()

        serializer = getMenuTreeSer(queryset, many=True)

        ResponseData = []

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["label"] = item["name"]
                # item["menuType"] = "一级菜单"
                ResponseData.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in ResponseData:
                    if firstMenu['id'] == item["parentId"]:
                        item["children"] = []
                        item["label"] = item["name"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

        for item in serializer.data:
            if item["menuType"] == '2':
                for firstMenu in ResponseData:
                    for secondMenu in firstMenu["children"]:
                        if secondMenu["id"] == item["parentId"]:
                            # item["menuType"] = "按钮"
                            item["label"] = item["name"]
                            secondMenu["children"].append(item)

        return SuccessResponse(ResponseData)


class getParentMenuView(APIView):
    """
    获取上级级菜单，新建菜单时使用
    """

    def get(self, request, *args, **kwargs):
        menuType = request.query_params["menuType"][0]
        queryset = Menu.objects.filter(Q(menuType=menuType)).all()
        serializer = ParentMenuSer(queryset, many=True)
        return SuccessResponse(serializer.data)


class getMenuByRoleView(APIView):

    def get(self, request, *args, **kwargs):
        role_id = request.query_params["role_id"]

        menus = Role.objects.get(pk=role_id).menu_set.all()
        menuList = []
        for item in menus:
            menuList.append(item.id)

        role = Role.objects.get(pk=role_id)

        responseDict = {
            "roleName": role.roleName,
            "remark": role.remark,
            "menuList": menuList

        }

        return SuccessResponse(responseDict)


class MenuByRoleView(APIView):
    """
        菜单和角色关系表
    """

    # 新增角色菜单
    def post(self, request, *args, **kwargs):

        roleId = request.data["roleId"]
        menuIds = request.data["menuData"]

        def setMenu(ro:Role):
            MenuSet = Menu.objects.filter(id__in=menuIds)
            # for item in MenuSet:
            #     item.role.set([ro])
            # pass

            ro.menu_set.set(MenuSet)

        if roleId:
            # 有角色
            role = Role.objects.get(id=roleId)
            setMenu(role)
        else:

            # 没有角色，先创建角色
            serializer = PostRoleSer(data={"roleName": request.data["roleName"],
                                           "remark": request.data.get("remark", "")
                                           })
            serializer.is_valid(raise_exception=True)
            role = serializer.save()
            setMenu(role)
        return SuccessResponse("保存成功")


class setRoleByUserView(APIView):
    """
    用户分配角色
    """

    def post(self, request, *args, **kwargs):

        # 保存数据
        userId = request.data["userId"]
        roleIds = request.data["roleIds"]
        user = User.objects.get(id=userId)
        roles = Role.objects.filter(id__in=roleIds)
        user.role_set.set(roles)

        return SuccessResponse("保存成功")


class getRoleByUserView(APIView):
    """
        查询用户的分配角色captcha_captchastore
    """

    def post(self, request, *args, **kwargs):
        userId = request.data.get("userId", None)
        responseDateList = []

        roles = Role.objects.all().values("id", "roleName")

        if userId:
            userRoles = Role.objects.filter(user__id=userId).all().values("id", "roleName")
            for role in roles:
                if role in userRoles:
                    role["checked"] = True
                responseDateList.append(role)
        responseDateList = roles

        return SuccessResponse(responseDateList)


class getRouteByUser(APIView):
    def get(self, request, *args, **kwargs):
        user = request.user

        """
        roles = UserRole.objects.filter(user_id=user.id).values("role_id")
        # [{'role_id': '1930036e-aeda-4c68-9975-bbdc6899601d'},{},...]

        # 获取当前用户所有角色的菜单ID（取并集）
        # 第一次遍历，获取按钮的二级菜单
        menuList = []
        for role in roles:
            menus = RoleMenu.objects.filter(role_id=role["role_id"]).values("menu__id", "menu__parentId",
                                                                            "menu__menuType")
            for menusId in menus:
                if menusId["menu__id"] not in menuList:
                    menuList.append(menusId["menu__id"])
                if menusId["menu__parentId"] not in menuList:
                    menuList.append(menusId["menu__parentId"])

        # 第二次遍历，获取按钮的一级菜单
        menus = Menu.objects.filter(id__in=menuList).values("id", "parentId", "menuType")
        for menusId in menus:
            if menusId["id"] not in menuList:
                menuList.append(menusId["id"])
            if menusId["parentId"] not in menuList:
                menuList.append(menusId["parentId"])

        # 超级管理员获取所有菜单
        if user.is_superuser:
            allMenu = Menu.objects.all()
        else:
            allMenu = Menu.objects.filter(id__in=menuList).all()

        # 用来添加到路由中
        Routes = []
        for menu in allMenu:
            if menu.menuType in ["1"]:
                Routes.append({
                    "path": menu.web_path,
                    "name": menu.web_path,
                    "meta": {
                        "icon": menu.icon,
                        "title": menu.name
                    },
                    "component": menu.component_path
                })

        # {
        #           id: 1,
        #           icon: 'el-icon-folder',
        #           title: '项目管理',
        #           children: [{
        #             id: 11,
        #             path: "/management",
        #             icon: 'el-icon-aim',
        #             title: '项目列表'
        #           }, {
        #             id: 12,
        #             path: "/setting_management",
        #             icon: 'el-icon-aim',
        #             title: '项目设置'
        #           },
        #           ]
        #         }
                
        # 用来添加到菜单中
        sidebarRouters = []
        webPath = []

        serializer = getMenuSidebarSer(allMenu, many=True)

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["title"] = item["name"]
                item["path"] = item["web_path"]
                # item["menuType"] = "一级菜单"
                sidebarRouters.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in sidebarRouters:
                    if firstMenu['id'] == item["parentId"]:
                        item["title"] = item["name"]
                        item["path"] = item["web_path"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

                        webPath.append(item["web_path"])

        # buttonPermission 按钮权限
        buttonPermission = []
        for item in serializer.data:
            if item["menuType"] == '2':
                buttonPermission.append(item["perms"])
        # 返回
        response = {
            "webPath": webPath,
            "routes": Routes,
            "sidebarRouters": sidebarRouters,
            "buttonPermission": buttonPermission
        }
        # logger.info(response)
        
        """
        # 查询用户的所有角色
        roles = user.role_set.all()
        logger.info(roles)
        logger.info(user.is_superuser)
        # 查询对应角色的菜单
        if user.is_superuser:
            menus = Menu.objects.all()
        else:
            menus = Menu.objects.filter(role__in=[roles]).all()

        # 用来添加到路由中
        Routes = []
        for menu in menus:
            if menu.menuType in ["1"]:
                Routes.append({
                    "path": menu.web_path,
                    "name": menu.web_path,
                    "meta": {
                        "icon": menu.icon,
                        "title": menu.name
                    },
                    "component": menu.component_path
                })

        # {
        #           id: 1,
        #           icon: 'el-icon-folder',
        #           title: '项目管理',
        #           children: [{
        #             id: 11,
        #             path: "/management",
        #             icon: 'el-icon-aim',
        #             title: '项目列表'
        #           }, {
        #             id: 12,
        #             path: "/setting_management",
        #             icon: 'el-icon-aim',
        #             title: '项目设置'
        #           },
        #           ]
        #         }

        # 用来添加到菜单中
        sidebarRouters = []
        webPath = []

        serializer = getMenuSidebarSer(menus, many=True)

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["title"] = item["name"]
                item["path"] = item["web_path"]
                # item["menuType"] = "一级菜单"
                sidebarRouters.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in sidebarRouters:
                    if firstMenu['id'] == item["parentId"]:
                        item["title"] = item["name"]
                        item["path"] = item["web_path"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

                        webPath.append(item["web_path"])

        # buttonPermission 按钮权限
        buttonPermission = []
        for item in serializer.data:
            if item["menuType"] == '2':
                buttonPermission.append(item["perms"])

        # 返回
        response = {
            "webPath": webPath,
            "routes": Routes,
            "sidebarRouters": sidebarRouters,
            "buttonPermission": buttonPermission
        }
        return SuccessResponse(response)
